package inge_soft.gestoriusNuevo.persistence.DAO.implementation;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import inge_soft.gestoriusNuevo.persistence.DAO.Exceptions.Implementation.ErrorMergeInstitucion;
import inge_soft.gestoriusNuevo.persistence.DAO.Exceptions.Implementation.UsuarioInexistenteException;
import inge_soft.gestoriusNuevo.persistence.DAO.abstraction.IActividadDAO;
import inge_soft.gestoriusNuevo.persistence.DAO.abstraction.IInstitucionDAO;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.Actividad;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.DomicilioTipificado;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.EstadoInstitucion;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.Evento;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.Institucion;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.Usuario;
import inge_soft.gestoriusNuevo.persistence.entity.implementation.UsuarioRegistrado;

@Repository("institucionDAO")
public class InstitucionDAO implements IInstitucionDAO {

	@PersistenceContext
	private EntityManager entityManager;
	
	// Obtiene las instituciones de un usuario
		public List<Institucion> obtenerInstituciones(Usuario usuario)
				throws DataAccessException {
			Collection<Institucion> instituciones;
			try {
				instituciones = usuario.getInstituciones();
			} catch (UsuarioInexistenteException e1) {
				throw e1;
			}
			return new ArrayList<Institucion>(instituciones);
		}
		
		
		// Agrega una institucion a la lista de instituciones de un usuario
		public void crearInstitucion(Usuario usuario,
				Institucion institucionNueva, EstadoInstitucion estadoInst) throws DataAccessException {
			try {
				
				institucionNueva.setUsuario(usuario);
				EstadoInstitucion estadoNuevaInstitucion = estadoInst;
				institucionNueva.setEstado(estadoNuevaInstitucion);
				institucionNueva.setDomicilios(new ArrayList<DomicilioTipificado>());
				entityManager.persist(institucionNueva);
				
				usuario.getInstituciones().add(institucionNueva);
				
			} catch (UsuarioInexistenteException e1) {
				throw e1;
			} catch (DataAccessException e2) {
				throw e2;
			}
			
		}
		
		//Modifica la institucion de un usuario
		public void modificarInstitucion(Usuario usuario,
				Institucion institucionModificada) throws DataAccessException {
			try {
				List<Institucion> instituciones = new ArrayList<Institucion>(usuario.getInstituciones());
				if (instituciones.contains(institucionModificada)) {
					boolean resultado = instituciones.remove(institucionModificada);
					System.out.println("Resultado: "+ resultado);
					entityManager.merge(institucionModificada);
					instituciones.add(institucionModificada);
					
				} else {
					throw new ErrorMergeInstitucion(
							"El usuario no posee esa institucion");
				}
			}
			catch (UsuarioInexistenteException e1) {
				throw e1;
			
			}
			catch(DataIntegrityViolationException e3){
				throw e3;
			}
			catch (DataAccessException e2) {
				throw e2;
			}		
		}
		
		public EstadoInstitucion buscarEstado(String estado){
			
			List<EstadoInstitucion> estadosPosibles =  obtenerEstadosInstitucion();
			EstadoInstitucion estadoElegido = null;
			for(EstadoInstitucion estadoActual:estadosPosibles){
				if(estadoActual.getEstado().equalsIgnoreCase(estado)){
					estadoElegido = estadoActual;
				}
			}
			
			return estadoElegido;
		}
		
		//Lista los estados posibles que puede tomar una institucion 
		public List<EstadoInstitucion> obtenerEstadosInstitucion(){
			return entityManager.createQuery("SELECT p FROM EstadoInstitucion p").getResultList();
		}

}
